package de.hauck.rtmidlet;

import java.io.IOException;
import java.util.Calendar;
import java.util.Vector;

import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import de.hauck.rtmidlet.model.Configuration;
import de.hauck.rtmidlet.model.StockBean;
import de.hauck.rtmidlet.model.StockStore;
import de.hauck.rtmidlet.utils.MyLogger;
import de.hauck.rtmidlet.utils.Utils;
import de.hauck.rtmidlet.views.CanvasCharts;
import de.hauck.rtmidlet.views.CanvasDummy;
import de.hauck.rtmidlet.views.CanvasImage;
import de.hauck.rtmidlet.views.CanvasSearch;
import de.hauck.rtmidlet.views.CanvasSplash;
import de.hauck.rtmidlet.views.CanvasYahoo;
import de.hauck.rtmidlet.views.FormAdHoc;
//import de.hauck.rtmidlet.views.FormChart;
import de.hauck.rtmidlet.views.FormSettingsMenu;
//import de.hauck.rtmidlet.views.FormWait;


public class RTMidlet extends MIDlet implements CommandListener {

	//TODO: SourceForge / Google CVS
	//TODO: JavaDocs
	//TODO: Trace aktivieren
	//TODO: weitere mobile Links?
	//TODO: WebService Abfrage
	//TODO: AdHoc Request
	//TODO: eingaben in richtigem type
	//TODO: How_to_get_System.out_output_from_a_MIDlet_and_save_it_to_a_file_in_S60_devices
	//TODO: yahooBean / StockBean Abgleich / yahoo exceptions fangen
	//TODO: refresh imagePreviews FT / download all in eigenem thread & confirm
	//TODO: BACK bei RTChart auch in SearchCanvas
	//TODO: filechooser fuer export/log-directory
	//TODO: %daily in yahoo
	//TODO: logviewer in eigenem thread
	//TODO: mobile finanz

	private static RTMidlet _rtmidlet;
	private Configuration c;
	private MyLogger logger;

	private Command cGetChart = new Command("Chart", Command.BACK, 1);
	private Command cOverviewYahoo = new Command("Overview Yahoo", Command.OK, 1);
	private Command cFinanztreff = new Command("Charts Finanztreff", Command.OK, 2);
	private Command cADVFN = new Command("Charts RT", Command.OK, 3);	
	private Command cSettings = new Command("Setup", Command.OK, 4);
	private Command cLink1 = new Command("Link Finanztreff", Command.OK, 5);
	private Command cLink2 = new Command("Link OnVista", Command.OK, 6);
	private Command cAbout = new Command("About", Command.OK, 7);
	private Command cSearch = new Command("Search", Command.OK, 8);
	private Command cLink3 = new Command("FT mobile", Command.OK, 9);
	private Command cAdHoc = new Command("AdHoc", Command.OK, 10);
	
	private Command cExit = new Command("Exit", Command.EXIT, 1);
	private Command cExitYes = new Command("Yes",Command.OK,1);
	private Command cExitNo = new Command("No",Command.BACK,1);
	
	private int lastSelected = 0;
	private Display _display;
	private Displayable _current;
	private StockStore myStore;
		
	//private FormChart _chartForm;
	//public FormWait _wForm;
	private FormSettingsMenu _settingsForm;
	
	private CanvasYahoo _yahooCanvas;
	private CanvasSearch _searchCanvas;
	private CanvasCharts _ftCanvas;
	private CanvasSplash _splashCanvas;
	private CanvasImage _imageCanvas;
	
	private List chartRTList;
	
	private Vector _filteredRTChartVec;

	public RTMidlet() {
		MyLogger.init();
		logger = MyLogger.getLogger();
		_rtmidlet = this;
	}
	
	public static RTMidlet getInstance(){
		return _rtmidlet;
	}
	protected void destroyApp(boolean arg0) {
		myStore.close();
	}

	protected void pauseApp() {
	}

	protected void startApp() throws MIDletStateChangeException {
		_splashCanvas = new CanvasSplash();
		_splashCanvas.show(false);
		_display = Display.getDisplay(this);
		_splashCanvas.showProgress("Loading Store...");
		myStore = new StockStore(); 
		//_splashCanvas.showProgress("Init Wait...");
		//_wForm = new FormWait();
		MyLogger.info(Utils.convertCal2DateTimeStamp(Calendar.getInstance())+" RTMidlet started");
		_splashCanvas.showProgress("Press a key");
	}

	void exitRequested() {
		MyLogger.info(Utils.convertCal2DateTimeStamp(Calendar.getInstance())+" RTMidlet ended");
		destroyApp(false);
		notifyDestroyed();
	}

	public List getRTChartList() {
		_filteredRTChartVec = myStore.getFilteredStockVector(Configuration.FILTER_CHART_RT);
		String[] menuElements = new String[_filteredRTChartVec.size()];
		for (int i=0; i<_filteredRTChartVec.size(); i++) {
			menuElements[i]=((StockBean)_filteredRTChartVec.elementAt(i)).getName();
		}
		
		chartRTList = new List("RT Charts", Choice.IMPLICIT, menuElements, null);
		if (chartRTList.size()<=lastSelected)
			chartRTList.setSelectedIndex(chartRTList.size()-1, true); else chartRTList.setSelectedIndex(lastSelected, true);
			
		chartRTList.addCommand(cExit);
		chartRTList.addCommand(cGetChart);
		chartRTList.addCommand(cOverviewYahoo);
		chartRTList.addCommand(cFinanztreff);
		chartRTList.addCommand(cADVFN);
		chartRTList.addCommand(cLink1);
		chartRTList.addCommand(cLink2);
		chartRTList.addCommand(cSettings);
		chartRTList.addCommand(cAbout);
		chartRTList.addCommand(cSearch);
		chartRTList.addCommand(cLink3);
		chartRTList.addCommand(cAdHoc);
		chartRTList.setSelectCommand(cGetChart);
		chartRTList.setCommandListener(this);
		return chartRTList;
	}
	
	public void commandAction(Command command, Displayable disp) { 
		_current = Display.getDisplay(this).getCurrent();
		lastSelected = chartRTList.getSelectedIndex();
		if (command == cGetChart) {
			StockBean selStock=(StockBean)_filteredRTChartVec.elementAt(chartRTList.getSelectedIndex());
			//System.out.println(selStock.getName());
			String symbol = selStock.getSymbolRT();
			String[] urls={
					Configuration.getURL(Configuration.RT, selStock.getSymbolRT()),
					Configuration.getURL(Configuration.INTRADAY, selStock.getSymbolTS()),
					Configuration.getURL(Configuration.TS, selStock.getSymbolTS()),
					Configuration.getURL(Configuration.FINANZTREFF, selStock.getSymbolFt())};
					
			
			if (null!=symbol&& !symbol.equals("")) {
				//if (chartName != null && !chartName.equals("")) {
					if (null==_imageCanvas) _imageCanvas = new CanvasImage(disp, urls);
					else _imageCanvas.setUrls(urls);
					_imageCanvas.downloadPic(selStock.getName(), 0);
					show(_imageCanvas);
				
				
//				String url = c.getURL(c.RT, symbol);
//				_wForm.setProgress(0, "");
//				_wForm.setNextDisplayable(_display, disp);
//				new DownloadThread(_wForm, selStock, url, _rtmidlet);
//				show(_wForm);
			} else {
				this.alert("Info", "No symbol maintained for "+selStock.getName(), Configuration.ALERT_WAIT_TIME);
				MyLogger.debug("No RT symbol maintained for "+selStock.getName());
			}
		} else if (command == cExit) {
			Alert exit_alert = new Alert ("Exit", "Do you really want to exit?",null,AlertType.CONFIRMATION);
			exit_alert.addCommand(cExitYes);
			exit_alert.addCommand(cExitNo);
			exit_alert.setCommandListener(this);
			exit_alert.setTimeout(5000);			
			_display.setCurrent(exit_alert);
		} else if (command==cExitYes) {
			try {
				myStore.saveStocks();
				myStore.saveConfig();
				//logger.debug("stocks & config saved");
			} catch (IOException e) {
				logger.error(e.getMessage());
				e.printStackTrace();
			}
			destroyApp(false);
			notifyDestroyed();
		} else if (command==cExitNo){
			showMenu();
		} else if (command == cOverviewYahoo) {			
			// must create new instance, maybe #-stocks changed
			_yahooCanvas = new CanvasYahoo(_display, _current, myStore.getFilteredStockVector(c.FILTER_OVERVIEW_YAHOO), myStore);
			new DownloadYahooThread(_yahooCanvas, myStore.getFilteredStockVector(c.FILTER_OVERVIEW_YAHOO), "http://download.finance.yahoo.com/d/quotes.csv?s=");
			//new DownloadYahooIndicesThread(_yahooCanvas, "http://download.finance.yahoo.com/d/quotes.csv?s=");
			show(_yahooCanvas);
		} else if (command == cFinanztreff) {			
			// must create new instance, maybe #-stocks changed
			_ftCanvas = new CanvasCharts(c.FILTER_CHART_FT, _display, _current, myStore.getFilteredStockVector(c.FILTER_CHART_FT), myStore);
			_display.setCurrent(_ftCanvas);
		} else if (command == cADVFN) {			
			// must create new instance, maybe #-stocks changed
			_ftCanvas = new CanvasCharts(c.FILTER_CHART_RT, _display, _current, myStore.getFilteredStockVector(c.FILTER_CHART_RT), myStore);
			show(_ftCanvas);
		} else if (command == cLink1) {
			try {
				this
						.platformRequest(c.linkFT);
			} catch (ConnectionNotFoundException e) {
				e.printStackTrace();
			}
		} else if (command == cLink2) {
			try {
				this
						.platformRequest(c.linkOV);
			} catch (ConnectionNotFoundException e) {
				e.printStackTrace();
			}
		} else if (command == cLink3) {
			CanvasDummy cd = new CanvasDummy(_current);
			_display.setCurrent(cd);
		} else if (command == cAdHoc) {
			FormAdHoc formAdHoc = new FormAdHoc(this);
			show(formAdHoc);
		} else if (command == cSettings) {
			if (_settingsForm==null) _settingsForm = new FormSettingsMenu(_display, _current, myStore, this);
			else show(_settingsForm.getSettingsMenu()); //show()); //_display.setCurrent(_settingsForm);
		} else if (command == cAbout) {
			_splashCanvas.show(true); //, _rtmidlet);			
		} else if (command == cSearch) {
			_searchCanvas = new CanvasSearch(_display, _current, myStore);
			show(_searchCanvas);
		}
	}

//	public void setChartForm(Image image, StockBean stock) {
//		if (_chartForm==null) _chartForm = new FormChart(image, _display, _current, chartRTList.getSelectedIndex(), 0, myStore, _rtmidlet, stock);
//		else _chartForm.setImage(image, stock);		
//		_display.setCurrent(_chartForm);
//	}
	
	 public void show(Displayable d) {
	    	try{
	    		Display.getDisplay(this).setCurrent(d);
	    	} catch (IllegalArgumentException iae) {    		
	    		logger.error("Could not display the new displayable " + d + ", " + iae.getMessage());
	    	}
			 /**
			  * Keep track of what the Midlet should be displaying.
			  * This is necessary, as a call to getDisplay following
			  * a setDisplay does not necessarily return the display just
			  * set, as the display actually gets set asynchronously.
			  * There also doesn't seem to be a way to find out what will
			  * be displayed next, or "serialise" on the setDisplay call.
			  * 
			  * This can cause problems, if an Alert is set just after
			  * a call to setDisplay. The call uses getDisplay to determine what
			  * to show after the Alert is dismissed, but the setDisplay might
			  * not have had an effect yet. Hence, keep manually track.
			  */
	    	_current=d;
			 //shouldBeDisplaying = d;		 
		}
	 public void showMenu() {
		 show(getRTChartList());
	 }
	 
	 public void alert(String title, String message, int timeout) {
	    	Alert alert = new Alert(title);
			alert.setTimeout(timeout);
			alert.setString(message);
			//#debug info
			//l.info("Showing Alert: " + message);
			try {
				if (_current== null)
					Display.getDisplay(this).setCurrent(alert);
				else
					Display.getDisplay(this).setCurrent(alert, _current);
			} catch (IllegalArgumentException iae) {
				/**
	    		 * Nokia S40 phones seem to throw an exception
	    		 * if one tries to set an Alert displayable when
	    		 * the current displayable is an alert too.
	    		 * 
	    		 * Not much we can do about this, other than just
	    		 * ignore the exception and not display the new
	    		 * alert. 
	    		 */
	    		//l.info("Could not display this alert (" + message + "), " + iae.getMessage());			
			}
	    }
	 
	 protected void keypressed(int key) {
			System.out.println(key);
	 }
	 
	 public StockStore getStockStore() {
		 return myStore;
	 }
	 
	 public void setCurrent(Displayable current) {
		_current=current; 
	 }
}
